/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.ufpb.halloc.dados;

import br.com.ufpb.halloc.exceptions.AtualizacaoDeProfessorException;
import br.com.ufpb.halloc.exceptions.ProfessorInexistenteException;
import br.com.ufpb.halloc.exceptions.ProfessorInvalidoException;
import br.com.ufpb.halloc.negocio.Disciplina;
import br.com.ufpb.halloc.negocio.Professor;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JOptionPane;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;

/**
 *
 * @author Filipe
 */
public class ProfessorDAOArquivoBin implements ProfessorDAO {

    private File arquivo;
    private ObjectInputStream in;
    private ObjectOutputStream out;
    
    private static ProfessorDAOArquivoBin daoArquivoBin; 
    
    
     public static ProfessorDAOArquivoBin getInstance(){
        if (daoArquivoBin == null)
            daoArquivoBin = new ProfessorDAOArquivoBin();
        return daoArquivoBin;
    }
    
    private ProfessorDAOArquivoBin(){
        arquivo = new File("Professores.bin");
    }
    
    @Override
    public void salvar(Professor p) {
       try {
           if (p.getMatricula()!=null || p.getMatricula()!="null"){
                if(!arquivo.exists()){
                    out = new ObjectOutputStream(new FileOutputStream(arquivo));
                    List<Professor> professores = new ArrayList<Professor>();
                      professores.add(p);
                     out.writeObject(professores);
                    out.flush();
                    out.close();
                  } else {
                    if (!existe(p)){
                        in = new ObjectInputStream(new FileInputStream(arquivo));
                        List<Professor> professores = (ArrayList<Professor>) in.readObject();
                        out = new ObjectOutputStream(new FileOutputStream(arquivo));
                        professores.add(p);
                        out.writeObject(professores);
                        out.flush();
                        out.close();
                        in.close();
                    } else {
                        throw new ProfessorInvalidoException("Este professor ja existe"); 
                    }  
                }
           } else {
               throw new ProfessorInvalidoException("Matricula Invalida!"); 
           }
       } catch (IOException exp1){
           exp1.printStackTrace();
       } catch (ClassNotFoundException exp2){
           exp2.printStackTrace();
       }
           
    }
    
    public boolean existe(Professor p){
       try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>)in.readObject();
            in.close();
            for (Professor pro : lista){
                if (pro.getMatricula().equals(p.getMatricula())) {
                    return true;
                }
            }
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return false;
    }

    @Override
    public void remover(Professor p) {
        try {
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> professores = (ArrayList<Professor>) in.readObject();
            in.close();
            int tam = professores.size();
            if (professores!=null){
                 for (Professor pro : professores){
                      if (pro.getMatricula().equals(p.getMatricula())){
                          professores.remove(pro);
                          break;
                      }          
                 }
                 if(professores.size()==tam){
                     throw new ProfessorInexistenteException("Não foi possível remover o professor.");
                  } else {
                    out = new ObjectOutputStream(new FileOutputStream(arquivo));
                    out.writeObject(professores);
                    out.flush();
                    out.close();
                  }
            } else {
                throw new ProfessorInexistenteException("Não existe Professores cadastrados.");
            }      
            
        } catch (IOException exp1) {
            exp1.printStackTrace();
        } catch (ClassNotFoundException exp2) {
            exp2.printStackTrace();
        }
    }

   

    @Override
    public void removerPorMatricula(String matricula) {
         try {
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> professores = (ArrayList<Professor>) in.readObject();
            in.close();
            int tam = professores.size();
            if (professores!=null){
                 for (Professor p : professores){
                      if (p.getMatricula().equals(matricula)){
                          professores.remove(p);
                          break;
                      }          
                 }
                 if(professores.size()==tam){
                     throw new ProfessorInexistenteException("Não foi possível remover o professor.");
                  } else {
                    out = new ObjectOutputStream(new FileOutputStream(arquivo));
                    out.writeObject(professores);
                    out.flush();
                    out.close();
                  }
            } else {
                throw new ProfessorInexistenteException("Não existe Professores cadastrados.");
            }      
            
        } catch (IOException exp1) {
            exp1.printStackTrace();
        } catch (ClassNotFoundException exp2) {
            exp2.printStackTrace();
        }
    }

    @Override
    public void atualizar(Professor p) {
        try {
            if (p.getMatricula()!=null || p.getMatricula()!="null") {
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>) in.readObject();
            int gambiarra = 0;
            System.out.println(lista.size());
            for (Professor pro : lista){
                
                if (pro.getMatricula().equals(p.getMatricula())) {
                    gambiarra = 1;
                    lista.remove(pro);
                    lista.add(p);
                }
            }
            if (gambiarra==1){
                out = new ObjectOutputStream(new FileOutputStream(arquivo));
                out.writeObject(lista);
                in.close();
                out.flush();
                out.close();
            } else {
                throw new AtualizacaoDeProfessorException("Não foi possível encontrar o professor e atualizar seus dados, "
                        + "verifique e tente novamente.");
            }
            } else {
                throw new AtualizacaoDeProfessorException("Matricula Invalida");
            }
	} catch (IOException exp1) {
            exp1.printStackTrace();
        } catch (ClassNotFoundException exp2) {
            exp2.printStackTrace();
	} catch (AtualizacaoDeProfessorException exp3){
            exp3.getMessage();
        }

	
    }

    @Override
    public Professor getProfessor(Professor p) {
        try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>)in.readObject();
            if (lista != null){
                 for (Professor pro : lista){
                    if (pro.getMatricula().equals(p.getMatricula())) {
                        return pro;
                    }
                }
            throw new ProfessorInexistenteException("Não foi possível encontrar este professor");
            } else {
                throw new ProfessorInexistenteException("Não existe Professores cadastrados.");
            } 
           
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return null;
    }

    

    @Override
    public Professor getProfessorMatricula(String matricula) {
       try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = new ArrayList<Professor>();
            lista = (ArrayList<Professor>)in.readObject();
            if (lista.size()!=0){
                for (Professor pro : lista){
                    
                    if (pro.getMatricula().equals(matricula) ) {
                      return pro;
                    }
                }
            } else {
                throw new ProfessorInexistenteException("Nao existe professores cadastrados no sistema");
            } 
            throw new ProfessorInexistenteException("Não foi possível encontrar este professor");
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return null;
    }

    @Override
    public List<Professor> getProfessores() {
        try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>)in.readObject();
            if (lista.size()==0){
                throw new ProfessorInexistenteException("Nenhum Professor Cadastrado Possui Projeto");
            }
            return lista;
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return null;
    }
    
    
    public int size(){
        List<Professor> lista = new ArrayList<Professor>();
	try {
            in = new ObjectInputStream(new FileInputStream(arquivo));
            lista = (ArrayList<Professor>) in.readObject();
            in.close();
            return lista.size();
	} catch (IOException exp1) {
            exp1.printStackTrace();
	} catch (ClassNotFoundException exp2) {
            exp2.printStackTrace();
	}
        
	return lista.size();
    }

    @Override
    public List<Professor> buscarTodosComProjeto() {
      List<Professor> retorno = new ArrayList<Professor>();
        try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>)in.readObject(); 
            in.close();
            if (!lista.isEmpty()){
                for(Professor pro : lista){
                if (pro.getProjetos().size()!=0){
                    retorno.add(pro);
                }
            }
            if (retorno.size()==0){
                throw new ProfessorInexistenteException("Nenhum Professor Cadastrado Possui Projeto");
            }
            } else {
                throw new ProfessorInexistenteException("Não existe Professores cadastrados.");
            }
            
            
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return retorno;
    }

    @Override
    public void inserirPreferencia(String codDisc, String codProf) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public List<Disciplina> getDisciplinasDePreferencia(String codProf) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void alocarDisciplia(String pro, String tur) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    
}
